[小ネタ]Javascriptで大きい桁の整数をJSONパースする時の注意点
JavascriptでJSONにパースしたいデータに大きい桁の整数があった場合は注意が必要です。
16桁を超えた数値を含む場合、超えた桁数分端数が丸め処理されてしまいます。
その場合、json-bigintを使って回避できます。
例
JSONとして解析する文字列
const jsonStr = '{"id": 6476060033855273896}';
Javascript標準ビルトインのJSON.parseでパースすると以下のようなデータになります。
JSON.parse(jsonStr); > { id: 6476060033855274000 } // (_□_;)!!
桁はそのままですが数値が変わってしまいました。エラーは出ていません。
json-bigintを使うと、
const JSONbig = require('json-bigint'); const jsonStr = '{"id": 6476060033855273896}'; JSONbig.parse(jsonStr); > { id: 6476060033855273896 }
このように正しくパースできました。
stringに変換する
ちなみに JSONbig.parse()
でパースした場合、データは以下のようなobjectとなっています。
const result = JSONbig.parse(jsonStr); console.log(typeof(result.id)); > object > result.id = { "s": 1, "c": [ 64760, 60033855273896 ], "e": 18, "_isBigNumber": true }
これをstringで取得するためには以下のように storeAsString
をtrueに指定することでstringに変換してくれます。
const JSONbig = require('json-bigint')({"storeAsString": true}); const result = JSONbig.parse(jsonStr); > result = { id: '6476060033855273896' } console.log(typeof(result.id)); > string
後続の処理でstringとして扱う場合は上記のオプションを使いましょう。
解説
そもそもなぜ、丸め処理されてしまうのかと言うと、JavaScriptの中で正確に扱える最大整数値(Number.MAX_SAFE_INTEGER)を超えているからです。
最大整数値を出力してみると、
console.log(Number.MAX_SAFE_INTEGER); > 9007199254740991
となります。
JSONの number
がECMAScriptの Numbers
に対応しているため、結果的にIEEE754の定める倍精度浮動小数点数として扱われているのが理由となります。
json-bigintや他のライブラリを使って回避しましょう。